/**
 * PerlaController - part of PerlaGis Architecture
 *
 * Copyright (C) 2010 Ricardo Gonzalez (gomnaz@gmail.com)
 * This program is free software: you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later version.
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 * Public License for more details.
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see http://www.gnu.org/licenses/
 */
package org.perla.services;

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.perla.managers.Sensor;
import org.perla.entities.Attitude;
import org.perla.entities.Bibi;
import org.perla.entities.Crackmeter;
import org.perla.entities.Temperature;
import org.perla.exceptions.NoSuchSensorException;
import org.perla.exceptions.WrongSensorTypeException;
import org.perla.managers.Gis;
import org.perla.managers.Notify;
import org.perla.managers.Value;

/**
 * Classe che rappresenta i servizi operativi del PerlaController.
 * Implementa i metodi necessari a richiedere gli ultimi valori per un dato sensore
 * e ad implementare la logica Push.
 *
 * @author Ricardo Gonzalez
 * @author Eva Gjeci
 */
@WebService()
public class Operative {

    @PersistenceContext(unitName = "PerlaController")
    EntityManager em;
    @PersistenceContext(unitName = "RelationController")
    private EntityManager emRelation;

    /**
     * Restituisce l'ultimio valore di un sensore Attitude
     * @param idGis la chiave del sensore all'interno del Gis
     * @return l'ultimo valore del sensore
     * @throws WrongSensorTypeException se il sensore non è di tipo Attitude
     * @throws NoSuchSensorException se non esiste un sensore relativo alla chiave passata
     */
    @WebMethod(operationName = "getLastAttitudeValue")
    public Attitude getLastAttitudeValue(@WebParam(name = "idGis") String idGis) throws WrongSensorTypeException, NoSuchSensorException {
        String idNodo = Notify.getIdNodo(Integer.parseInt(idGis), emRelation);
        return Value.getLastAttitude(Sensor.get(idNodo, "ATTITUDE_" + idNodo, em), em);
    }

    /**
     * Restituisce l'ultimio valore di un sensore Bibi
     * @param idGis la chiave del sensore all'interno del Gis
     * @return l'ultimo valore del sensore
     * @throws WrongSensorTypeException se il sensore non è di tipo Bibi
     * @throws NoSuchSensorException se non esiste un sensore relativo alla chiave passata
     */
    @WebMethod(operationName = "getLastBibiValue")
    public Bibi getLastBibiValue(@WebParam(name = "idGis") String idGis) throws WrongSensorTypeException, NoSuchSensorException {
        String idNodo = Notify.getIdNodo(Integer.parseInt(idGis), emRelation);
        return Value.getLastBibi(Sensor.get(idNodo, "BIBI_" + idNodo, em), em);
    }

    /**
     * Restituisce l'ultimio valore di un sensore Crackmeter
     * @param idGis la chiave del sensore all'interno del Gis
     * @return l'ultimo valore del sensore
     * @throws WrongSensorTypeException se il sensore non è di tipo Crackmeter
     * @throws NoSuchSensorException se non esiste un sensore relativo alla chiave passata
     * @deprecated Dovrebbe restituire due sensori e non uno
     */
    @WebMethod(operationName = "getLastCrackmeterValue")
    public Crackmeter getLastCrackmeterValue(@WebParam(name = "idGis") String idGis) throws WrongSensorTypeException, NoSuchSensorException {
        String idNodo = Notify.getIdNodo(Integer.parseInt(idGis), emRelation);
        //return Value.getLastCrackmeter(Sensor.get(idNodo, "CRACKMETER_"+idNodo, em), em);
        return null;
    }

    /**
     * Restituisce l'ultimio valore di un sensore Temperature
     * @param idGis la chiave del sensore all'interno del Gis
     * @return l'ultimo valore del sensore
     * @throws WrongSensorTypeException se il sensore non è di tipo Temperature
     * @throws NoSuchSensorException se non esiste un sensore relativo alla chiave passata
     */
    @WebMethod(operationName = "getLastTemperatureValue")
    public Temperature getLastTemperatureValue(@WebParam(name = "idGis") String idGis) throws WrongSensorTypeException, NoSuchSensorException {
        String idNodo = Notify.getIdNodo(Integer.parseInt(idGis), emRelation);
        return Value.getLastTemperature(Sensor.get(idNodo, "TEMPERATURE_" + idNodo, em), em);
    }

    /**
     * Invia gli ultimi valori a GisController per il nodo passato come parametro
     * @param idNodo la chiave del nodo per cui bisogna inviare i valori
     * @return true se l'invio è avvenuto correttamente
     */
    @WebMethod(operationName = "sendUpdate")
    public boolean sendUpdate(@WebParam(name = "idNodo") String idNodo) {
        try {
            Gis.sendUpdate(idNodo, em, emRelation);
        } catch (NoSuchSensorException ex) {
            Logger.getLogger(Operative.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        }
        return true;
    }
}
